package scala.Extractor

object MainOB {
   def main(args: Array[String]): Unit = {
      val gmail = "hung@gmail"
      val isMail = mailValid(gmail)
      println(isMail)

      val m = "DIDI@gmail.com"
      val m1 = "Didi@gmail.com"
      val m2 = "didi@gmail.com"
      println(userTwiceUpper(m))
      println(userTwiceUpper(m1))
      println(userTwiceUpper(m2))
   }

   def mailValid(mail: String): Boolean = {
      mail match {
         case Email(_, _) => true
         case _           => false
      }
   }

   def userTwiceUpper(mail: String): String = {
      mail match {
         case Email(Twice(x @ UpperCase()), domain) => {

            "'" + mail + "' : match '" + x + "' in " + domain
         }
         case _ => "'" + mail + "' : No Match !"
      }
   }
}

object Email {
   //this is injection
   def apply(user: String, domain: String): String = user + "@" + domain

   //this is extraction (extractor pattern)
   def unapply(mail: String): Option[(String, String)] = {
      val parts = mail.split("@")
      if (parts.length == 2) Some(parts(0), parts(1)) else None
   }
}

//check that a string is formed of two same string, ex : DIDI, DDDD, DADA, abcabc..
object Twice {
   def apply(s: String): String = s + s
   def unapply(s: String): Option[String] = {
      val half = s.substring(0, s.length / 2)
      val another = s.substring(s.length / 2)
      if (half == another) Some(half) else None
   }
}
/* Sometimes , extractor pattern doesn't bind any variable
 * In that case the corresponding "unapply" method returns 
 * a boolean—true for success and false for failure.
 * see this example
 */
object UpperCase {
   def unapply(s: String): Boolean = {
      if (s.toUpperCase == s) true
      else false
   }
}

object Domain {
   //injector , it is optional
   def apply(parts: String*): String = parts.reverse.mkString(".")
   //extractor , it is mandatory
   def unapply(wholeString: String): Option[Seq[String]] = {
      Some(wholeString.split("\\.").reverse)
   }
}
/*
 * 
 * 
 * 
 * 
 * 
 */
